#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
typedef double db;
int n,m,T;
inline int rd(){
    int x=0,w=1;char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') w=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<3)+(x<<1)+(c^48);
        c=getchar();
    }
    return x*w;
}
struct f{
    ll a,b;
    f(ll a=0,ll b=0):a(a),b(b){}
    bool operator <(f y) const{
        return a*y.b<b*y.a;
    }
    bool operator >(f y) const{
        return a*y.b>b*y.a;
    }
    bool operator <=(f y) const{
        return a*y.b<=b*y.a;
    }
    bool operator >=(f y) const{
        return a*y.b>=b*y.a;
    }
    bool operator ==(f y) const{
        return a*y.b==b*y.a;
    }
};
f div(f x,f y){
    return f(x.a*y.b,x.b*y.a);
}
f mlt(f x,f y){
    return f(x.a*y.a,x.b*y.b);
}
f add(f x,f y){
    return f(x.a*y.b+x.b*y.a,x.b*y.b);
}
int vl,L;
f p[N];
int tot;
struct node{
    int v,a;
    f d;
}car[N];
struct req{
    int l,r;
}nd[N];
int cnt;
int gt(f x){
    int res=lower_bound(p+1,p+m+1,x)-p;
    return res;
}
int gt2(f x){
    int res=upper_bound(p+1,p+m+1,x)-p;
    return res;
}
void work1(int cur){
    if(car[cur].v<=vl||car[cur].d>p[m]) return;
    int l,r=m;
    l=gt(car[cur].d);
    tot++;
    cnt++;nd[cnt].l=l;nd[cnt].r=r;
}
void work2(int cur){
    int l,r=m;
    if(car[cur].v>vl){
        if(car[cur].d>p[m]) return;
        tot++;
        l=gt(car[cur].d);
        cnt++;nd[cnt].l=l;nd[cnt].r=r;
        return;
    }
    f x=f(vl*vl-car[cur].v*car[cur].v,2*car[cur].a);
    x=add(x,car[cur].d);
    if(x>=p[m]) return;
    tot++;
    l=gt2(x);
    cnt++;nd[cnt].l=l;nd[cnt].r=r;
}
void work3(int cur){
    int l,r;
    if(car[cur].v<=vl) return;
    f x=f(-vl*vl+car[cur].v*car[cur].v,-2*car[cur].a);
    x=add(x,car[cur].d);
    l=gt(car[cur].d);
    r=gt(x);
    if(p[r]>=x) r--;
    if(r<l) return;
    tot++;
    cnt++;nd[cnt].l=l;nd[cnt].r=r;
}
int cmp(const req &a,const req &b){
    return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void work(){
    for(int i=1;i<=n;i++){
        if(car[i].a==0){
            work1(i);
        }
        else if(car[i].a>0){
            work2(i);
        }
        else work3(i);
    }
    int ans=0;
    sort(nd+1,nd+cnt+1,cmp);
    int cu=0;
    for(int i=1;i<=cnt;i++){
        if(nd[i].l>cu){
            ans++;cu=nd[i].r;
        }
    }
    printf("%d %d\n",tot,m-ans);
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    T=rd();
    for(int o=1;o<=T;o++){
        //scanf("%d%d",&n,&m);
        //scanf("%d",&tmp);L=tmp;
        //scanf("%d",&tmp);vl=tmp;
        n=rd(),m=rd();
        L=rd(),vl=rd();
        for(int i=1;i<=n;i++){
            //scanf("%d%d%d",&tmp,&tmp2,&tmp3);
            car[i].d=f(rd(),1);car[i].v=rd();car[i].a=rd();
        }
        for(int i=1;i<=m;i++){
            //scanf("%d",&tmp);p[i]=f(tmp,1);
            p[i]=f(rd(),1);
        }
        cnt=0;tot=0;
        sort(p+1,p+m+1);
        work();
    }
    return 0;
}
